﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Domain.Dummies;
using Domain.Dummies.Dtos;
using Domain.Dummies.Dtos.Collections;
using AutoMapper;

namespace UniversalConsoleTester
{
    public class BaseClass
    {
        public Guid Id;
        public string Name;
    }

    public class ProvidedClass : BaseClass
    {
        public IEnumerable<int> _somestuff;
    }

    public class TestClass
    {
        public static void TestScheduleDatabaseFunctionality(TeacherWeekFullDataScheduleDto week)
        {             
            Console.WriteLine("At day {0} ({1}) for teacher with Id={2}, Name={3}",
                week.RequestedWeek.Day, week.RequestedWeek.DayOfWeek,
                week.Teacher.Id, week.Teacher.Name);

            foreach (TeacherDayItemWSScheduleDto day in week.Days)
            {
                Console.WriteLine("=================================");
                Console.WriteLine(day.WeekDay);
                if (day.Lines != null)
                foreach (TeacherLineWSScheduleDto line in day.Lines)
                {
                    Console.WriteLine("-----------------------------");
                    Console.WriteLine("in {0} at {1} will be subject id={2}, hours={3}, name={4}",
                        line.Auditory, line.Time.TimeOfDay,
                        line.Subject.Id, line.Subject.Hours, line.Subject.Name);

                    if (line.GroupsGuids != null)
                    foreach (Guid groupguid in line.GroupsGuids)
                        Console.WriteLine("   group={0}", groupguid);
                }
            }

        }

        public static void TestScheduleServiceFunctionality()
        {
            TeacherWeekFullDataScheduleDto week = Database.KorchomkinWeekFullDataSchedule;
            
            Mapper.CreateMap<TeacherLineWSScheduleDto, TeacherLineScheduleDto>().
                ForMember(dst => dst.SubjectGuid, opt => opt.MapFrom(src => src.Subject.Id));
            Mapper.AssertConfigurationIsValid();

            
            TeacherWeekScheduleDto dockweek = new TeacherWeekScheduleDto();
            List<TeacherDayItemScheduleDto> dockdays = new List<TeacherDayItemScheduleDto>();
            dockweek.Days = dockdays;
            dockweek.RequestedWeek = week.RequestedWeek;
            dockweek.TeacherGuid = week.Teacher.Id;

            foreach (TeacherDayItemWSScheduleDto day in week.Days)
            {                
                TeacherDayItemScheduleDto dockday = new TeacherDayItemScheduleDto();
                dockday.WeekDay = day.WeekDay;                
                
                List<TeacherLineScheduleDto> docklines = new List<TeacherLineScheduleDto>();
                dockday.Lines = docklines;              

                if (day.Lines != null)
                foreach(TeacherLineWSScheduleDto line in day.Lines)
                {
                    TeacherLineScheduleDto dockline = Mapper.Map<TeacherLineWSScheduleDto, TeacherLineScheduleDto>(line);
                    docklines.Add(dockline);
                }
                dockdays.Add(dockday);
            }

            Console.WriteLine("=========DOCK_VARIANT======");
            Console.WriteLine("At day {0} ({1}) for teacher {2}",
                dockweek.RequestedWeek.Day, dockweek.RequestedWeek.DayOfWeek,
                dockweek.TeacherGuid);
            
            foreach (TeacherDayItemScheduleDto dockday in dockweek.Days)
            {
                Console.WriteLine("=================================");
                Console.WriteLine(dockday.WeekDay);

                if (dockday.Lines != null)
                foreach (TeacherLineScheduleDto dockline in dockday.Lines)
                {
                    Console.WriteLine("-----------------------------");
                    Console.WriteLine("in {0} at {1} will be subject {2}",
                        dockline.Auditory, dockline.Time.TimeOfDay,
                        dockline.SubjectGuid);

                    if (dockline.GroupsGuids != null)
                    foreach (Guid groupguid in dockline.GroupsGuids)
                        Console.WriteLine("   group={0}", groupguid);
                }
            }
        }

        public static void TestScheduleServiceDayFuntionality()
        {
            Mapper.CreateMap<TeacherLineWSScheduleDto, TeacherLineScheduleDto>().
                ForMember(dst => dst.SubjectGuid, opt => opt.MapFrom(src => src.Subject.Id));
            Mapper.AssertConfigurationIsValid();

            TeacherWeekFullDataScheduleDto week = Database.KorchomkinWeekFullDataSchedule;
            DateTime targetdate = DateTime.Parse("12.01.2011");

            TeacherDayScheduleDto dockday = new TeacherDayScheduleDto();
            List<TeacherLineScheduleDto> docklines = new List<TeacherLineScheduleDto>();
            dockday.TeacherGuid = week.Teacher.Id;
            dockday.RequestedDay = targetdate;
            dockday.Lines = docklines;
            
            IEnumerable<TeacherDayItemWSScheduleDto> query = week.Days.Where(day => day.WeekDay.Equals(targetdate.DayOfWeek));
            if (query.Count() != 0 && query.First().Lines != null)
            {
                foreach (TeacherLineWSScheduleDto line in query.First().Lines)
                    docklines.Add(Mapper.Map<TeacherLineWSScheduleDto, TeacherLineScheduleDto>(line));
                
            }

            Console.WriteLine("=========TeacherDayScheduleDto==========");
            Console.WriteLine("At day {0} for teacher {1}", dockday.RequestedDay, dockday.TeacherGuid);

            if (dockday.Lines != null)
                foreach (TeacherLineScheduleDto dockline in dockday.Lines)
                {
                    Console.WriteLine("-----------------------------");
                    Console.WriteLine("in {0} at {1} will be subject {2}",
                        dockline.Auditory, dockline.Time.TimeOfDay,
                        dockline.SubjectGuid);

                    if (dockline.GroupsGuids != null)
                        foreach (Guid groupguid in dockline.GroupsGuids)
                            Console.WriteLine("   group={0}", groupguid);
                }

            //return dockday;
        }

        public static void TestMapper()
        {
            Mapper.CreateMap<ExamWithSubjectAndTeacherDto, ExamDto>()
                .ForMember(dst => dst.SubjectGuid, opt => opt.MapFrom(src => src.Subject.Id))
                .ForMember(dst => dst.TeacherGuid, opt => opt.MapFrom(src => src.Teacher.Id));
            Mapper.AssertConfigurationIsValid();

            ExamListDto _for_return = new ExamListDto();
            _for_return.StudentGuid = Database.TimurExams.Student.Id;
            _for_return.Exams = Database.TimurExams.Exams
                .Select(item => Mapper.Map<ExamWithSubjectAndTeacherDto, ExamDto>(item))
                .ToList();

            Console.WriteLine("StudentId={0}", _for_return.StudentGuid);
            foreach (var exam in _for_return.Exams)
            {
                Console.WriteLine("{0} {1} {2} {3} {4} {5}",
                    exam.Id,
                    exam.Auditory,
                    exam.Date,
                    exam.Mark,
                    exam.SubjectGuid,
                    exam.TeacherGuid);
            }
        }

        public static void PropertiesTester()
        {
            BookDto book = new BookDto();
            book.Author = "Л. Н. Толстой";
            book.Year = 1856;

            if (book.Id.Equals(Guid.Empty))
                Console.WriteLine("Guid empty");

            foreach (System.Reflection.PropertyInfo prop in book.GetType().GetProperties())
            {
                Console.Write("Property = {0}", prop.Name);

                Object value = prop.GetValue(book, null);
                if (value is System.Guid)
                {
                    if (!value.Equals(System.Guid.Empty))
                        Console.Write("  Value = {0}", value);
                }
                else
                    if (value is System.String)
                    {
                        if (value != null)
                            Console.Write("  Value = {0}", value);
                    }
                    else
                        if (value is System.Int32)
                        {
                            if (!value.Equals(0))
                                Console.Write("  Value = {0}", value);
                        }
                Console.WriteLine();
            }
            Console.WriteLine("===============================================");

            if (book.Id.Equals(Guid.Empty))
                Console.WriteLine("book.Id is not set");
            if (book.Author == null)
                Console.WriteLine("book.Author is not set");
            if (book.Title == null)
                Console.WriteLine("book.Title is not set");
            if (book.Year == 0)
                Console.WriteLine("book.Year is not set");
            if (book.PagesCount == 0)
                Console.WriteLine("book.PagesCount is not set");

        }

        
        public static void SearchBookByAuthorOrTitle()
        {
            BookDto book = new BookDto();
            book.Author = "Горький";
            //book.Year = 1856;
            List<System.Reflection.PropertyInfo> info = new List<System.Reflection.PropertyInfo>();
            BooksBaseListDto target = new BooksBaseListDto();

            foreach (System.Reflection.PropertyInfo prop in book.GetType().GetProperties())
            {
                Object value = prop.GetValue(book, null);

                if ((value == null)                                           ||
                    (value is System.Guid  && value.Equals(System.Guid.Empty))||
                    (value is System.Int32 && value.Equals(0))
                   )continue;
                

                info.Add(prop);
            }

                        
            IEnumerable<BookDto> query = Database.get().Books.Where(
                delegate(BookDto mybook)
                {
                    bool result = true;

                    foreach (var prop in info)
                    {
                        Object value = prop.GetValue(book, null);
                        if (value is String)
                            result &= (prop.GetValue(mybook, null) as String).ToUpper().IndexOf((value as String).ToUpper()) >= 0;
                        else
                            result &= prop.GetValue(mybook, null).Equals(value);
                    }

                    return result;
                });

            if (query.Count() > 0)
                target.Books = query.ToList();
            else
                target.Books = new List<BookDto>();


            Console.WriteLine("===============FINISH==================");
            foreach (BookDto ibook in target.Books)            
                Console.WriteLine("Id={0}, Author={1}, Title={2}, PagesCount={3}, Year={4}",
                    ibook.Id,
                    ibook.Author,
                    ibook.Title,
                    ibook.PagesCount,
                    ibook.Year);
            
        }

        public static void GetListOfBooksGotByPerson(Guid targetPerson)
        {
            BooksListDto booklist = new BooksListDto();            
            booklist.HolderPersonGuid = targetPerson;

            var query = Database.get().WhoGetBook.Where(who => who.HolderPerson.Id.Equals(targetPerson));
            if (query.Count() != 0)
                booklist.Books = query.First().Books;
            else
                booklist.Books = new List<BookDto>();


            Console.WriteLine("WhoGotBookId={0}",
                booklist.HolderPersonGuid);
            foreach(var ibook in booklist.Books)
                Console.WriteLine("Id={0}, Author={1}, Title={2}, PagesCount={3}, Year={4}",
                    ibook.Id,
                    ibook.Author,
                    ibook.Title,
                    ibook.PagesCount,
                    ibook.Year);
        }
    }
}
